<?php
declare(strict_types=1);

namespace WebApp\lib\db;

use Redis;
use ServerApp\lib\core\ServerStation;
use SplQueue;
use Swoole\Coroutine\Redis as CRedis;

/**
 * Class RedisUtil
 * @package server\lib
 */
abstract class RedisPool
{
    /**
     * @var SplQueue
     */
    protected $pool;

    private $useCo = true;

    /**
     * plugin_version constructor.
     */
    public function __construct()
    {
        if (ServerStation::$wId === null) {
            $this->useCo = false;
            $this->pool = new Redis();
            $this->pool->connect($this->getHost(), $this->getPort());
        } else {
            $this->useCo = true;
            $this->pool = new SplQueue;
        }
    }

    abstract public function getHost(): string;
    abstract public function getPort(): int;

    /**
     * @param $func
     * @return mixed
     */
    public function exec($func)
    {
        if (!$this->useCo) {
            return $func($this->pool);
        } else {
            $client = $this->get();
            $res = $func($client);
            $this->put($client);
            return $res;
        }
    }

    /**
     * @param Redis $client
     */
    public function put($client)
    {
        $this->pool->push($client);
    }

    public function get()
    {
        //有空闲连接
        if (count($this->pool) > 0) {
            return $this->pool->pop();
        }

        //无空闲连接，创建新连接
        $redis = new CRedis();
        $res = $redis->connect($this->getHost(), (int)$this->getPort());
        if ($res == false) {
            return false;
        } else {
            return $redis;
        }
    }
}
